<?php
/*
 * Last modified: 2012-09-27
 */

require_once 'lib.php';



/**
 * MySQLGuestbook 
 *
 * MySQL implementation
 * 
 * @author Kirill Krasnoschekov
 */ 
class MySQLGuestbook extends Guestbook
{
    // Database descriptor
    private $db;
    
    // Table names  
    private $msgTable = "gb_message";
    private $commentTable = "gb_comment";

    // Error text messages
    protected static $err = array(
        'CONNECT' => 'Connection error!',
        'SELECT_DB' => 'Database selection error!',
        'ID_NOT_INT' => 'Id is not integer!',
        'MSGID_NOT_FOUND' => 'No message with given Id found!',
        'COMMENTID_NOT_FOUND' => 'No comment with given Id found!');



    /**
     * Constructor
     * 
     * Establists connection to the database
     */ 
    public function __construct
    ($server, $username, $password, $dbname)
    {
        // Connecting
        $this->db = mysql_connect($server, $username, $password) 
            or die(self::$err['CONNECT']);
            
        // Selecting database
        mysql_select_db($dbname, $this->db) 
            or die(self::$err['SELECT_DB']);
    }
    
    /**
     * Destructor
     * 
     * Closes connection to the database
     */
    public function __destruct() 
    {
        mysql_close($this->db);
    }



    /**
     * CountPages
     * 
     * Counts amount of pages in the guestbook
     * 
     * @return int Amount of pages (starting with 0)
     */
    public function CountPages()
    {
        $result = $this->Query("SELECT COUNT(*) FROM {$this->msgTable}");
        $count = mysql_result($result, 0); 
        
        return ceil($count / $this->messagesPerPage);
    }

    
    /**
     * FetchMessages
     * 
     * Fetches messages from the given page
     * 
     * @param $page Page number
     */
    public function FetchMessages($page)
    {
        // Calculating message numbers on the given page
        $numStart = $page * $this->messagesPerPage;
        $numEnd = $numStart + $this->messagesPerPage;

        // Selecting messages from given page
        $result = $this->Query(
            "SELECT id, name, text, timestamp 
            FROM {$this->msgTable}
            ORDER BY timestamp DESC
            LIMIT {$numStart}, {$numEnd}");
            
       // Fetching them into array
        $messages = array();
        for ($i = 0; $rec = mysql_fetch_assoc($result); $i++)
        {
            $messages[$i] = $rec;
        }

        return $messages;
    }
    
    /**
     * FetchComments
     * 
     * Fetch comments for the given message
     * 
     * @param $msgid Message ID
     */
    public function FetchComments($msgid)
    {
        // Selecting comments for given message
        $result = $this->Query(
            "SELECT id, name, text, timestamp
            FROM {$this->commentTable} 
            WHERE msgid=" . mysql_escape_string($msgid) .
            " ORDER BY timestamp");
        
        // Fetching them into array
        $comments = array();
        for ($i = 0; $rec = mysql_fetch_assoc($result); $i++)
        {
            $comments[$i] = $rec;
        }
        
        return $comments;
    }



    /**
     * AddMessage
     * 
     * Add a message to the guestbook
     * 
     * @param $name User name
     * @param $text Message text
     */
    public function AddMessage($name, $text)
    {
        // Screening
        $name = mysql_escape_string($name);
        $text = mysql_escape_string($text);
        
        // Inserting
        // id and timestamp are added automatically
        $this->Query(
            "INSERT INTO {$this->msgTable} (name, text) 
            VALUES ('{$name}', '{$text}')");    
        
        return True;
    }
    
    /**
     * AddComment
     * 
     * Add a comment to the given message
     * 
     * @param integer $msgid Message id
     * @param string $name User name
     * @param string $text Comment text
     */
    public function AddComment($msgid, $name, $text)
    {
        // Checking if message does not exist
        $this->MessageExists($msgid) or die(self::$err['MSGID_NOT_FOUND']);
        
        // Screening
        $name = mysql_escape_string($name);
        $text = mysql_escape_string($text);
        
        // Inserting
        // id and timestamp are added automatically
        $this->Query(
            "INSERT INTO {$this->commentTable} (msgid, name, text) 
            VALUES ('{$msgid}', '{$name}', '{$text}')");    
        
        return True;
    }
    
    /**
     * DeleteMessage
     * 
     * Delete the message from the guestbook
     * 
     * @param int $msg_id ID of the message to delete
     */
    public function DeleteMessage($msgid)
    {
        // Checking if message does not exist
        $this->MessageExists($msgid) or die(self::$err['MSGID_NOT_FOUND']);
        
        // Deleting all the comments to this message
        $this->Query("DELETE FROM {$this->commentTable} WHERE msgid={$msgid}");
        
        // Deleting the message
        $this->Query("DELETE FROM {$this->msgTable} WHERE id={$msgid}");
        
        return True;
    }
    
    /**
     * DeleteComment
     * 
     * Delete the comment from the guestbook
     * 
     * @param int $commentid ID of the comment to delete
     */
    public function DeleteComment($commentid)
    {
        // Checking if comment does not exist
        $this->CommentExists($commentid) or die(self::$err['COMMENTID_NOT_FOUND']);
        
        // Deleting
        $this->Query("DELETE FROM $this->commentTable WHERE id=$commentid");
        
        return True;
    }
    
    /**
     * UpdateMessage
     * 
     * Update selected message
     * 
     * @param int $msgid Message ID
     * @param string $name New user name
     * @param string $text New message text
     */
    public function UpdateMessage($msgid, $name, $text)
    {
        $this->MessageExists($msgid) or die(self::$err['MSGID_NOT_FOUND']);

        // Screening
        $name = mysql_escape_string($name);
        $text = mysql_escape_string($text);

        // Updating
        $this->Query
            ("UPDATE {$this->msgTable} 
            SET name='{$name}', text='{$text}' WHERE id={$msgid}");
        
        return True;
    }
    

        
    /**
     * MessageExists
     * 
     * @param int $msgid Message ID
     * @return True if yes, False if no
     */    
    protected function MessageExists($msgid)
    {
        // Checking the type
        if (gettype($msgid) != "integer")
        {
            die(self::$err['ID_NOT_INT']);
        }

        // Checking if there is a message with given id
        if (mysql_num_rows($this->Query
            ("SELECT * FROM {$this->msgTable} WHERE id={$msgid}")) == 0)
        {
            return False;
        }
        
        return True;                
    }
    
    /**
     * CommentExists
     * 
     * @param int $commentid Comment ID
     * @return True if yes, False if no
     */    
    protected function CommentExists($commentid)
    {
        // Checking the type
        if (gettype($commentid) != "integer")
        {
            die(self::$err['ID_NOT_INT']);
        }

        // Checking if there is a message with given id
        if (mysql_num_rows($this->Query
            ("SELECT * FROM {$this->commentTable} WHERE id={$commentid}")) == 0)
        {
            return False;
        }
        
        return True;
    }   
    
    

    /**
     * Query
     * 
     * Makes a query and checks DB for errors
     * 
     * @param string $query
     * @return resource $result
     */
    private function Query($query)
    {
        $result = mysql_query($query);
        $this->CheckDBError();
        return $result;
    }

    /**
     * CheckDBError
     * 
     * Checks MySQL error and dies if it happened
     */
    private function CheckDBError()
    {
        if ($errno = mysql_errno())
        {
            // Exit program with an error
            die("Error $errno: " . mysql_error());
        }
                
        return True;
    }
}

?>